#include "formslave.h"
#include "ui_formslave.h"
#include "Effects/RGB_Slave/RGB_Slave.h"
#include "formmasks.h"
#include "Curve/hsv.h"

FormSlave::FormSlave(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::FormSlave)
{
    ui->setupUi(this);
    setToolTip("RGB调试助手");
    setWindowTitle("RGB调试助手");
    connect(ui->radioButton_Ack,    SIGNAL(clicked()), this, SLOT(clicked()));
    connect(ui->radioButton_Sleep,  SIGNAL(clicked()), this, SLOT(clicked()));
    connect(ui->radioButton_Init,   SIGNAL(clicked()), this, SLOT(clicked()));
    connect(ui->radioButton_Ctrl,   SIGNAL(clicked()), this, SLOT(clicked()));
    connect(ui->radioButton_Udef,   SIGNAL(clicked()), this, SLOT(clicked()));
    connect(ui->radioButton_Record, SIGNAL(clicked()), this, SLOT(clicked()));
    connect(ui->radioButton_Direct, SIGNAL(clicked()), this, SLOT(clicked()));
    connect(ui->radioButton_D1,     SIGNAL(clicked()), this, SLOT(clicked()));
    connect(ui->radioButton_D2,     SIGNAL(clicked()), this, SLOT(clicked()));
    connect(ui->radioButton_D3,     SIGNAL(clicked()), this, SLOT(clicked()));
    connect(ui->radioButton_Read,   SIGNAL(clicked()), this, SLOT(clicked()));
    connect(ui->radioButton_Test,   SIGNAL(clicked()), this, SLOT(clicked()));
    ui->radioButton_Init->setChecked(true);
    ui->groupBox_format->setTitle("格式: | 0x5C | cmd | data |~0x5C|");
    clicked();
    adjustSize();
}

FormSlave::~FormSlave()
{
    disconnect(ui->radioButton_Ack,    SIGNAL(clicked()), this, SLOT(clicked()));
    disconnect(ui->radioButton_Sleep,  SIGNAL(clicked()), this, SLOT(clicked()));
    disconnect(ui->radioButton_Init,   SIGNAL(clicked()), this, SLOT(clicked()));
    disconnect(ui->radioButton_Ctrl,   SIGNAL(clicked()), this, SLOT(clicked()));
    disconnect(ui->radioButton_Udef,   SIGNAL(clicked()), this, SLOT(clicked()));
    disconnect(ui->radioButton_Record, SIGNAL(clicked()), this, SLOT(clicked()));
    disconnect(ui->radioButton_Direct, SIGNAL(clicked()), this, SLOT(clicked()));
    disconnect(ui->radioButton_D1,     SIGNAL(clicked()), this, SLOT(clicked()));
    disconnect(ui->radioButton_D2,     SIGNAL(clicked()), this, SLOT(clicked()));
    disconnect(ui->radioButton_D3,     SIGNAL(clicked()), this, SLOT(clicked()));
    disconnect(ui->radioButton_Read,   SIGNAL(clicked()), this, SLOT(clicked()));
    disconnect(ui->radioButton_Test,   SIGNAL(clicked()), this, SLOT(clicked()));
    delete ui;
}

static uint32_t kb_color(const uint32_t color)
{
    hsv_t hsv = { 0, 0, 0 };
    rgb2hsv(color, &hsv);
    //hsv.hue = 0;
    hsv.saturation = 255;
    hsv.value = 255;
    return hsv2rgb(&hsv);
}
void FormSlave::clicked()
{
    const struct kbRGB_ctrl_t *const ctrl = FormMasks::Get();
    //static const uint32_t kb_matrix_masks[6] = {0x0001FFFD, 0x001FFFFF, 0x001FFFFF, 0x000E2FFF, 0x001EAFFD, 0x000BFC47};
    uint8_t buf[128*3];
    int len;
    union RGB_Slave_t slave;
    memset(buf, 0x00, sizeof(buf));
    memset(&slave, 0x00, sizeof(slave));
    if(ui->radioButton_Ack->isChecked())
    {
        slave.head = RGB_SLAVE_HEAD;
        slave.cmd = RGB_SLAVE_CMD_ACK;
        slave.ack._cmd = RGB_SLAVE_CMD_INIT;
        slave.ack.code = 0;
        slave.ack.check = 0x33;
        len = rgb_slave_ack(buf, slave.ack._cmd, slave.ack.code, slave.ack.check);
        showArg("| head | cmd | _cmd | code | check | end |",
             "参考:| 0x5C | 0xFF|  1B  |  1B  |  1B   |~0x5C| 6B",
             buf, len);
    }
    if(ui->radioButton_Sleep->isChecked())
    {
        len = rgb_slave_sleep(buf);
        showArg("| head | cmd | end |",
             "参考:| 0x5C | 0x00|~0x5C| 3B ",
             buf, len);
    }
    if(ui->radioButton_Init->isChecked())
    {
        slave.head = RGB_SLAVE_HEAD;
        slave.cmd = RGB_SLAVE_CMD_INIT;
        slave.init.cols = 21;
        slave.init.rows = 6;
        if(0==ctrl->Horizontal) slave.init.rows |= 0x80;
        slave.init.IdxLogo = 0xFF;
        slave.init.reverseX = 0x55;
        slave.init.reverseY = 0x00;
        slave.init.masks[2] = 0x67893322;
        //slave.init.palettes[3] = 0x44556633;
        slave.init.palettes[1] = kb_color(0xFFFF0000);//0xFFFF0000;  // 红
        slave.init.palettes[2] = kb_color(0xFFFFA500);//0xFFFFA500;  // 橙
        slave.init.palettes[3] = kb_color(0xFFFFFF00);//0xFFFFFF00;  // 黄
        slave.init.palettes[4] = kb_color(0xFF00FF00);//0xFF00FF00;  // 绿
        slave.init.palettes[5] = kb_color(0xFF00FFFF);//0xFF00FFFF;  // 青
        slave.init.palettes[6] = kb_color(0xFF0000FF);//0xFF0000FF;  // 蓝
        slave.init.palettes[7] = kb_color(0xFFFF00FF);//0xFFFF00FF;  // 紫
        slave.init.palettes[0] = 0;
        len = rgb_slave_init(buf, slave.init.cols, slave.init.rows, ctrl->IdxLogo, ctrl->reverseX, ctrl->reverseY, ctrl->Masks, slave.init.palettes);
        showArg("| head | cmd | cols | rows | IdxLogo| RevX | RevY | masks| palettes| end |",
             "参考:| 0x5C | 0x01|  21  |  6   |  1B    |  1B  |  4B  |  24B |   32B   |~0x5C| 67B",
             buf, len);
    }
    if(ui->radioButton_Ctrl->isChecked())
    {
        slave.head = RGB_SLAVE_HEAD;
        slave.cmd = RGB_SLAVE_CMD_CTRL;
        slave.control.IdxMode = 10;
        slave.control.Speed = 10;
        slave.control.background = 0x00;
        slave.control.logo = 0xFF00FFFF;
        slave.control.keys[3] = 0xAABBCCDD;
        slave.control.normally = 2;
        slave.control.reverse = 1;
        slave.control.Grayscale = 0x4F;
        len = rgb_slave_ctrl(buf, ctrl->IdxMode, ctrl->Speed, ctrl->reverse, slave.control.Grayscale, slave.control.background, slave.control.logo, ctrl->keys, slave.control.normally);
        showArg("| head | cmd | Mode | Speed | Rev | Gray| back | logo | keys | norm | end |",
             "参考:| 0x5C | 0x02|  1B  |  1B   | 1B  | 1B  |  4B  |  4B  |  24B |  1B  |~0x5C| 40B",
             buf, len);
    }
    if(ui->radioButton_Udef->isChecked())
    {
        slave.head = RGB_SLAVE_HEAD;
        slave.cmd = RGB_SLAVE_CMD_UDEF;
        //slave.transfer.offset = 21;
        for(int col_id=0; col_id<RGB_SLAVE_KB_COLS; col_id++)
        {
            for(int row_id=0; row_id<RGB_SLAVE_KB_ROWS; row_id++)
            {
                slave.transfer_rgb[row_id*RGB_SLAVE_KB_COLS+col_id] = col_id%8;
            }
        }
        len = rgb_slave_udef(buf, slave.transfer_rgb);
        showArg("| head | cmd | offset | rgb | end |",
             "参考:| 0x5C | 0x03|126B |~0x5C| 129B",
             buf, len);
    }
    if(ui->radioButton_Record->isChecked())
    {
        slave.head = RGB_SLAVE_HEAD;
        slave.cmd = RGB_SLAVE_CMD_RECORD;
        //slave.transfer.offset = 42;
        slave.transfer_rgb[11] = 0xCC;
        len = rgb_slave_record(buf, slave.transfer_rgb);
        showArg("| head | cmd | rgb | end |",
             "参考:| 0x5C | 0x03|126B |~0x5C| 129B",
             buf, len);
    }
    if(ui->radioButton_Direct->isChecked())
    {
        uint32_t rgb[RGB_SLAVE_KB_ROWS*RGB_SLAVE_KB_COLS];
        memset(rgb, 0x00, sizeof(rgb));
        slave.head = RGB_SLAVE_HEAD;
        slave.cmd = RGB_SLAVE_CMD_DIRECT;
        //slave.transfer.offset = 21;
        slave.direct_rgb[11] = 0xCC;
        //rgb[0] = 0x778899;
        hsv_t hsv = { 0, 0, 0 };
        //hsv.hue = 0;
        hsv.saturation = 255;
        hsv.value = 255;
        for(int col_id=0; col_id<RGB_SLAVE_KB_COLS; col_id++)
        {
            for(int row_id=0; row_id<RGB_SLAVE_KB_ROWS; row_id++)
            {
                hsv.hue = col_id*360/21;
                rgb[row_id*RGB_SLAVE_KB_COLS+col_id] = hsv2rgb(&hsv);
            }
        }
        len = rgb_slave_direct(buf, rgb);
        showArg("| head | cmd | rgb | end |",
             "参考:| 0x5C | 0x05|378B |~0x5C| 381B",
             buf, len);
    }
    if(ui->radioButton_D1->isChecked())
    {
        //uint32_t rgb[RGB_SLAVE_KB_ROWS*RGB_SLAVE_KB_COLS];
        //memset(rgb, 0x00, sizeof(rgb));
        slave.head = RGB_SLAVE_HEAD;
        slave.cmd = RGB_SLAVE_CMD_DIRECT1;
        slave.direct_rgb[11] = 0xCC;
        memset(slave.direct_rgb, 0x00, sizeof(slave.direct_rgb));
        //rgb[0] = 0x778899;
        hsv_t hsv = { 0, 0, 0 };
        //hsv.hue = 0;
        hsv.saturation = 255;
        hsv.value = 255;
        for(int col_id=0; col_id<RGB_SLAVE_KB_COLS; col_id++)
        {
            for(int row_id=0; row_id<RGB_SLAVE_KB_ROWS; row_id++)
            {
                hsv.hue = col_id*360/21;
                slave.direct_rgb[row_id*RGB_SLAVE_KB_COLS+col_id] = hsv2rgb(&hsv);
            }
        }
        len = rgb_slave_direct_sub(buf, slave.cmd, slave.direct_rgb);
        showArg("| head | cmd | rgb | end |",
             "参考:| 0x5C | 0x08|126B |~0x5C| 129B",
             buf, len);
    }
    if(ui->radioButton_D2->isChecked())
    {
        //uint32_t rgb[RGB_SLAVE_KB_ROWS*RGB_SLAVE_KB_COLS];
        //memset(rgb, 0x00, sizeof(rgb));
        slave.head = RGB_SLAVE_HEAD;
        slave.cmd = RGB_SLAVE_CMD_DIRECT2;
        slave.direct_rgb[11] = 0xCC;
        memset(slave.direct_rgb, 0x00, sizeof(slave.direct_rgb));
        //rgb[0] = 0x778899;
        hsv_t hsv = { 0, 0, 0 };
        //hsv.hue = 0;
        hsv.saturation = 255;
        hsv.value = 255;
        for(int col_id=0; col_id<RGB_SLAVE_KB_COLS; col_id++)
        {
            for(int row_id=0; row_id<RGB_SLAVE_KB_ROWS; row_id++)
            {
                hsv.hue = col_id*360/21;
                slave.direct_rgb[row_id*RGB_SLAVE_KB_COLS+col_id] = hsv2rgb(&hsv);
            }
        }
        len = rgb_slave_direct_sub(buf, slave.cmd, slave.direct_rgb);
        showArg("| head | cmd | rgb | end |",
             "参考:| 0x5C | 0x09|126B |~0x5C| 129B",
             buf, len);
    }
    if(ui->radioButton_D3->isChecked())
    {
        //uint32_t rgb[RGB_SLAVE_KB_ROWS*RGB_SLAVE_KB_COLS];
        //memset(rgb, 0x00, sizeof(rgb));
        slave.head = RGB_SLAVE_HEAD;
        slave.cmd = RGB_SLAVE_CMD_DIRECT3;
        slave.direct_rgb[11] = 0xCC;
        memset(slave.direct_rgb, 0x00, sizeof(slave.direct_rgb));
        //rgb[0] = 0x778899;
        hsv_t hsv = { 0, 0, 0 };
        //hsv.hue = 0;
        hsv.saturation = 255;
        hsv.value = 255;
        for(int col_id=0; col_id<RGB_SLAVE_KB_COLS; col_id++)
        {
            for(int row_id=0; row_id<RGB_SLAVE_KB_ROWS; row_id++)
            {
                hsv.hue = col_id*360/21;
                slave.direct_rgb[row_id*RGB_SLAVE_KB_COLS+col_id] = hsv2rgb(&hsv);
            }
        }
        len = rgb_slave_direct_sub(buf, slave.cmd, slave.direct_rgb);
        showArg("| head | cmd | rgb | end |",
             "参考:| 0x5C | 0x0A|126B |~0x5C| 129B",
             buf, len);
    }
    if(ui->radioButton_Read->isChecked())
    {
        slave.head = RGB_SLAVE_HEAD;
        slave.cmd = RGB_SLAVE_CMD_READ;
        //slave.read.offset = 33;
        len = rgb_slave_read(buf/*, slave.read.offset*/);
        showArg("| head | cmd | end |",
             "参考:| 0x5C | 0x06|~0x5C| 3B",
             buf, len);
    }
    if(ui->radioButton_Test->isChecked())
    {
        slave.head = RGB_SLAVE_HEAD;
        slave.cmd = RGB_SLAVE_CMD_TEST;
        slave.test.col = 0;
        slave.test.row = 0;
        slave.test.IdxLogo = 0xFF;
        slave.test.reverseX = 0x55;
        slave.test.reverseY = 0x00;
        slave.test.masks[2] = 0x67893322;
        slave.test.color    = 0x44556633;
        len = rgb_slave_test(buf, slave.test.col, slave.test.row, ctrl->IdxLogo, ctrl->reverseX, ctrl->reverseY, ctrl->Masks, slave.test.color);
        showArg("| head | cmd | col | row | IdxLogo| RevX | RevY | masks| color | end |",
             "参考:| 0x5C | 0x07|  1B |  1B |  1B    |  1B  |  4B  |  24B |  4B   |~0x5C| 39B",
             buf, len);
    }
}

void FormSlave::showArg(QString format, QString example, const uint8_t buf[128], const int len)
{
    const char HEX[] = "0123456789ABCDEF";
    char data[1024*3];
    int cnt;
    for(cnt=0; cnt<len; cnt++)
    {
        data[3*cnt+0] = HEX[(buf[cnt]>>4)&0x0F];
        data[3*cnt+1] = HEX[(buf[cnt]>>0)&0x0F];
        data[3*cnt+2] = ' ';
        data[3*cnt+3] = '\0';
    }
     data[3*cnt+0] = '\0';
    ui->lineEdit_format->setText(format);
    ui->groupBox_data->setTitle(example);
    ui->textEdit_data->setText(QString(data));
}
